package ${package.Controller?replace(".controller","")}.config.common.service.impl;


import ${package.Controller?replace(".controller","")}.config.common.annotation.Log;
import ${package.Controller?replace(".controller","")}.config.common.service.LogService;
import ${package.Entity}.TbLog;
import ${package.ServiceImpl}.TbLogServiceImpl;
import ${package.Service}.TbLogService;
import ${package.Controller?replace(".controller","")}.util.AddressUtil;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.LocalVariableTableParameterNameDiscoverer;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.Serializable;
import java.lang.reflect.Method;
import java.sql.Timestamp;
import java.util.*;

/**
* @author yiming
* @title: LogServiceImpl
* @projectName property
* @description: TODO
* @date 2019/6/119:24
*/
@Service
public class LogServiceImpl  implements LogService {
@Autowired
ObjectMapper objectMapper;
@Autowired
TbLogService tbLogService;
@Override
public boolean save(TbLog tbLog) {
return tbLogService.save(tbLog);
}
@Override
public void saveLog(ProceedingJoinPoint proceedingJoinPoint, TbLog log) throws JsonProcessingException {
MethodSignature signature = (MethodSignature) proceedingJoinPoint.getSignature();
Method method = signature.getMethod();
Log annotation = method.getAnnotation(Log.class);
if (annotation != null) {
//注解上的描述
log.setOperation(annotation.value());
}
//请求的类名
String className = proceedingJoinPoint.getTarget().getClass().getName();
//请求方法名
String methodName = signature.getName();
log.setMethod(className + "." + methodName + "()");
//请求的方法参数
Object[] args = proceedingJoinPoint.getArgs();
//请求的方法参数名称
LocalVariableTableParameterNameDiscoverer d = new LocalVariableTableParameterNameDiscoverer();
String[] parameterNames = d.getParameterNames(method);
if (args != null && parameterNames != null) {
StringBuilder params = new StringBuilder();
params = handleParams(params, args, Arrays.asList(parameterNames));
log.setParams(params.toString());
}
log.setCreateTime(new Timestamp(System.currentTimeMillis()));
log.setLocation(AddressUtil.getAddress(log.getIp()));
this.save(log);
}

private StringBuilder handleParams(StringBuilder params, Object[] args, List<String> paramNames) throws JsonProcessingException {
    for (int i = 0; i < args.length; i++) {
    if (args[i] instanceof Map) {
    Set set = ((Map) args[i]).keySet();
    List list = new ArrayList();
    List paramList = new ArrayList();
    for (Object key : set) {
    list.add(((Map) args[i]).get(key));
    paramList.add(key);
    }
    return handleParams(params, list.toArray(), paramList);
    } else {
    if (args[i] instanceof Serializable) {
    Class<?> clazz = args[i].getClass();
    try {
    clazz.getDeclaredMethod("toString", new Class[]{null});
    //如果不抛出NoSuchMethodException异常，则存在ToString方法
    params.append(" ").append(paramNames.get(i)).append(objectMapper.writeValueAsString(args[i]));
    } catch (NoSuchMethodException e) {
    params.append(" ").append(paramNames.get(i)).append(objectMapper.writeValueAsString(args[i].toString()));
    }
    } else if (args[i] instanceof MultipartFile) {
    MultipartFile file = (MultipartFile) args[i];
    params.append(" ").append(paramNames.get(i)).append(": ").append(file.getName());
    } else {
    params.append(" ").append(paramNames.get(i)).append(": ").append(args[i]);
    }
    }
    }
    return params;
    }
    }